package cn.stylefeng.guns.modular.gridsystem.utils;

import cn.hutool.core.thread.ThreadUtil;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MusicPlayer {

    private AudioFormat audioFormat;
    private AudioFormat sourceAudioFormat;
    private boolean isPlaying = false;
    private SourceDataLine sourceDataLine;

    private ArrayBlockingQueue<byte[]> audioDataBuffer = new ArrayBlockingQueue<>(100);

    private ExecutorService mThreadPool = Executors.newFixedThreadPool(1);
    private Future<?> currentTask = null;

    public MusicPlayer(int sampleRate, int bitDepth, int channels) throws LineUnavailableException {
        this.audioFormat = new AudioFormat(sampleRate, bitDepth, channels, true, false);
//        this.sourceAudioFormat = new AudioFormat(sampleRate, bitDepth, channels, true, false);
        this.sourceDataLine = AudioSystem.getSourceDataLine(audioFormat);
    }

    private boolean isInit = false;

    public void start() throws LineUnavailableException {
        if (isPlaying) return;
        isPlaying = true;
        sourceDataLine.open(audioFormat, 16000);
        sourceDataLine.start();

        currentTask = mThreadPool.submit(() -> {
            while (true) {
                while (audioDataBuffer.size() < 10) {
                    ThreadUtil.sleep(500);
                }
                final byte[] take = audioDataBuffer.take();
                long start = System.currentTimeMillis();
                sourceDataLine.write(take, 0, take.length);
                System.out.println("time:" + (System.currentTimeMillis() - start));
            }
        });
    }


    public void stop() {
        isPlaying = false;
        sourceDataLine.drain();
        sourceDataLine.stop();
        sourceDataLine.close();
    }

    public void writeData(byte[] data) {
        long start = System.currentTimeMillis();
        audioDataBuffer.offer(data);
        System.out.println("offser:" + (System.currentTimeMillis() - start));
    }


}
